package net.sinmetal.twitcockpit.service;

import java.util.ArrayList;
import java.util.List;

import net.sinmetal.twitcockpit.exception.ConfigRuntimeException;
import net.sinmetal.twitcockpit.meta.config.AuthUserMeta;
import net.sinmetal.twitcockpit.meta.config.TwitterConfigMeta;
import net.sinmetal.twitcockpit.model.config.AuthUser;
import net.sinmetal.twitcockpit.model.config.TwitterConfig;

import org.slim3.datastore.Datastore;
import org.slim3.memcache.Memcache;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.Transaction;

/**
 * ConfigService
 *
 * @author Sinmetal
 *
 */
public class ConfigService {

    /** TwitterConfigMeta */
    private TwitterConfigMeta twitterConfigMeta = TwitterConfigMeta.get();

    /** AuthUserMeta */
    private AuthUserMeta authUserMeta = AuthUserMeta.get();

    /**
     * TwitterConfig取得
     *
     * @return TwitterConfig
     */
    public TwitterConfig getTwitterConfig() {
        String twitterConfigKey = TwitterConfig.getKeyName();
        String memcacheKey =
            this.getClass().getCanonicalName() + twitterConfigKey;
        if (Memcache.contains(memcacheKey)) {
            return Memcache.get(memcacheKey);
        }

        Key key = Datastore.createKey(twitterConfigMeta, twitterConfigKey);
        try {
            TwitterConfig config = Datastore.get(twitterConfigMeta, key);
            Memcache.put(memcacheKey, config);
            return config;
        } catch (Exception e) {
            throw new ConfigRuntimeException(e);
        }
    }

    /**
     * TwitterConfig設定
     *
     * @param consumerKey
     * @param consumerSecret
     */
    public TwitterConfig setTwitterConfig(String consumerKey,
            String consumerSecret) {
        String twitterConfigKey = TwitterConfig.getKeyName();
        String memcacheKey =
            this.getClass().getCanonicalName() + twitterConfigKey;

        Key key = Datastore.createKey(twitterConfigMeta, twitterConfigKey);
        TwitterConfig config =
            TwitterConfig.getInstance(key, consumerKey, consumerSecret);

        Transaction tx = Datastore.beginTransaction();
        Datastore.put(config);
        tx.commit();

        Memcache.put(memcacheKey, config);

        return config;
    }

    /**
     * AuthUserを返す
     *
     * @return AuthUserが存在しない場合はnull
     */
    public AuthUser getAuthUser() {
        Key key = AuthUser.createKey();
        AuthUser authUser = Datastore.getOrNull(authUserMeta, key);
        return authUser;
    }

    /**
     * AuthUserEmailsを返す。
     *
     * @return AuthUserが存在しない場合は、空のListを返す
     */
    public List<String> getAuthUserEmails() {
        AuthUser authUser = getAuthUser();
        if (authUser == null) {
            return new ArrayList<String>();
        }
        return authUser.getEmails();
    }

    /**
     * AuthUserのEmailを追加する Emailが重複した場合は無視する
     *
     * @param emails
     * @return
     */
    public Key addAuthUser(String email) {
        Key key = AuthUser.createKey();
        AuthUser authUser = Datastore.getOrNull(authUserMeta, key);
        if (authUser == null) {
            authUser = AuthUser.getInstance();
            authUser.setKey(key);
        }
        authUser.addAuthUser(email);
        return Datastore.put(authUser);
    }
}
